// // Copyright (c) 2009 All Right Reserved // // vl // // 2009-01-01 // Contains ... using System; using System.Diagnostics.Contracts; using System.Globalization; using System.Text; using System.Xml.Serialization; namespace LargoCommon.Music { /// Musical system. /// System is prototype of so called formal GSystem. It is defined by /// its order. System Contains a simple support for converting indexes into formal indexes. /// It serves as a common superclass for harmonic and rhythmical GSystem. /// Class helps to work with binary structures. [Serializable] [XmlRoot] public class GeneralSystem { /// Maximum (now supported) number of the system order. public const byte MaxOrder = 24; /// /// System degree. /// private byte degree; /// /// System order. /// private byte order; #region Constructors /// Initializes a new instance of the GeneralSystem class. Serializable. public GeneralSystem() { } /// Initializes a new instance of the GeneralSystem class. /// Degree of system. /// Order of system. public GeneralSystem(byte degree, byte order) { if (degree == 0) { throw new ArgumentException("Degree of system must not be 0."); } if (order == 0) { throw new ArgumentException("Order of system must not be 0."); } this.Degree = degree; this.Order = order; this.Median = (byte)(this.Order / 2); } #endregion #region Properties /// Gets or sets degree of the system. /// Degree=2 for binary systems. public byte Degree { get { Contract.Ensures(Contract.Result() > 0); if (this.degree <= 0) { throw new InvalidOperationException("Degree is not positive number."); } return this.degree; } set { if (value <= 0) { throw new ArgumentException("Degree must be positive number.", nameof(value)); } this.degree = value; } } /// Gets or sets order of the system, i.e. total number of bits). /// Property description. public byte Order { get { Contract.Ensures(Contract.Result() > 0); if (this.order <= 0) { throw new InvalidOperationException("Order is not positive number."); } return this.order; } set { if (value <= 0) { throw new ArgumentException("Order must be positive number.", nameof(value)); } this.order = value; } } /// Gets or sets median i.e. half order of the system. /// Property description. [XmlIgnore] public byte Median { get; set; } #endregion #region Static methods /// /// Convert Struct. /// /// Structural number. /// System Order From. /// System Order To. /// Returns value. public static long ConvertStruct(long structNumber, byte sysOrderFrom, byte sysOrderTo) { //// byte sysDegree if (sysOrderFrom == sysOrderTo) { return structNumber; } var rstruct = 0L; for (byte indexFrom = 0; indexFrom < sysOrderFrom; indexFrom++) { if (!BinaryNumber.ElementIsOn(structNumber, indexFrom)) { continue; } var ito = (byte)(int)Math.Round((double)indexFrom * sysOrderTo / sysOrderFrom); rstruct = rstruct | BinaryNumber.BitAt(ito); } //// long rstruct = (long)struct * (long)((Math.Pow(sysDegree, sysOrderTo) - 1) / (Math.Pow(sysDegree, sysOrderFrom) - 1)); return rstruct; } /// Converts the integer index to its formal system representative element. /// Order of the system. /// Real system length. /// Returns value. [JetBrains.Annotations.PureAttribute] public static byte FormalLength(byte order, int sysLength) { if (order == 0) { return 0; } //// Time optimization if (sysLength < 0) { //// if (sysLength < -order) { sysLength += order + order; } while (sysLength < 0) { sysLength += order; } } else { if (sysLength < order) { return (byte)sysLength; } while (sysLength >= order) { sysLength -= order; } } //// int frmLength = sysLength % order; //// return (byte)((frmLength < 0) ? (frmLength + order) : frmLength); return (byte)sysLength; } #endregion /// Returns symbols for given element. /// Returns value. [JetBrains.Annotations.PureAttribute] public long LongSize() { return (long)Math.Pow(this.Degree, this.Order); } /// Returns symbols for given element. /// Returns value. [JetBrains.Annotations.PureAttribute] public decimal DecimalSize() { return (decimal)Math.Pow(this.Degree, this.Order); } /// Converts the integer index to its formal system representative element. /// Real system length. /// Returns value. [JetBrains.Annotations.PureAttribute] public byte FormalLength(int sysLength) { return FormalLength(this.Order, sysLength); } /// Converts the integer index to its formal system representative number. /// Real system length. /// Returns value. [JetBrains.Annotations.PureAttribute] public int FormalMedianLength(int sysLength) { int frmLength = this.FormalLength(sysLength); return frmLength <= this.Median ? frmLength : (frmLength - this.Order); } #region String representation /// String representation of the object. /// Returns value. [JetBrains.Annotations.PureAttribute] public override string ToString() { var s = new StringBuilder(); s.AppendFormat(CultureInfo.CurrentCulture, "${0,2}", this.Order.ToString("D", CultureInfo.CurrentCulture.NumberFormat)); return s.ToString(); } #endregion } }